package com.sddnytsh.body_buildingsystem.network

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.sddnytsh.body_buildingsystem.config.NetworkConfig
import com.sddnytsh.body_buildingsystem.topic.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.util.concurrent.TimeUnit

/**
 * 饮食模块API服务类
 * 处理与fitness-send的HTTP通信
 */
class DietApiService {
    
    private val client = OkHttpClient.Builder()
        .connectTimeout(5, TimeUnit.SECONDS)
        .readTimeout(8, TimeUnit.SECONDS)
        .writeTimeout(5, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
        .build()
    
    private val gson = Gson()
    
    /**
     * 获取食物分类列表
     */
    suspend fun getFoodCategories(): Result<List<String>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/food-info/categories")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "分类API返回的data: $data")
                    // 根据后端逻辑，categories在data.categories中
                    val categories = data?.get("categories") as? List<*>
                    val categoryList = categories?.map { it.toString() } ?: emptyList()
                    android.util.Log.d("DietApiService", "解析出的分类列表: $categoryList")
                    Result.success(categoryList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取食物分类失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 获取所有食物信息
     */
    suspend fun getAllFoods(): Result<List<FoodInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/food-info")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "获取所有食物API返回的data: $data")
                    // 根据后端逻辑，foods在data.foods中
                    val foods = data?.get("foods") as? List<*>
                    val foodList = foods?.map { foodData ->
                        val foodMap = foodData as Map<*, *>
                        FoodInfo(
                            id = (foodMap["id"] as? Number)?.toLong() ?: 0L,
                            name = foodMap["name"] as? String ?: "",
                            calories = (foodMap["calories"] as? Number)?.toDouble() ?: 0.0,
                            carbohydrates = (foodMap["carbohydrates"] as? Number)?.toDouble() ?: 0.0,
                            protein = (foodMap["protein"] as? Number)?.toDouble() ?: 0.0,
                            fat = (foodMap["fat"] as? Number)?.toDouble() ?: 0.0,
                            category = foodMap["category"] as? String ?: "",
                            createdAt = foodMap["createdAt"] as? String ?: "",
                            updatedAt = foodMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("DietApiService", "解析出的食物列表大小: ${foodList.size}")
                    Result.success(foodList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取食物信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 根据分类获取食物信息
     */
    suspend fun getFoodsByCategory(category: String): Result<List<FoodInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/food-info/category/$category")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "获取分类食物API返回的data: $data")
                    // 根据后端逻辑，foods在data.foods中
                    val foods = data?.get("foods") as? List<*>
                    val foodList = foods?.map { foodData ->
                        val foodMap = foodData as Map<*, *>
                        FoodInfo(
                            id = (foodMap["id"] as? Number)?.toLong() ?: 0L,
                            name = foodMap["name"] as? String ?: "",
                            calories = (foodMap["calories"] as? Number)?.toDouble() ?: 0.0,
                            carbohydrates = (foodMap["carbohydrates"] as? Number)?.toDouble() ?: 0.0,
                            protein = (foodMap["protein"] as? Number)?.toDouble() ?: 0.0,
                            fat = (foodMap["fat"] as? Number)?.toDouble() ?: 0.0,
                            category = foodMap["category"] as? String ?: "",
                            createdAt = foodMap["createdAt"] as? String ?: "",
                            updatedAt = foodMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("DietApiService", "解析出的分类食物列表大小: ${foodList.size}")
                    Result.success(foodList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取分类食物信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 搜索食物信息
     */
    suspend fun searchFoods(keyword: String): Result<List<FoodInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/food-info/search?keyword=$keyword")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "搜索食物API返回的data: $data")
                    // 根据后端逻辑，foods在data.foods中
                    val foods = data?.get("foods") as? List<*>
                    val foodList = foods?.map { foodData ->
                        val foodMap = foodData as Map<*, *>
                        FoodInfo(
                            id = (foodMap["id"] as? Number)?.toLong() ?: 0L,
                            name = foodMap["name"] as? String ?: "",
                            calories = (foodMap["calories"] as? Number)?.toDouble() ?: 0.0,
                            carbohydrates = (foodMap["carbohydrates"] as? Number)?.toDouble() ?: 0.0,
                            protein = (foodMap["protein"] as? Number)?.toDouble() ?: 0.0,
                            fat = (foodMap["fat"] as? Number)?.toDouble() ?: 0.0,
                            category = foodMap["category"] as? String ?: "",
                            createdAt = foodMap["createdAt"] as? String ?: "",
                            updatedAt = foodMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("DietApiService", "解析出的搜索食物列表大小: ${foodList.size}")
                    Result.success(foodList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "搜索食物信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 创建饮食记录
     */
    suspend fun createDietRecord(dietRecord: DietRecordCreateRequest): Result<FoodRecordItem> = withContext(Dispatchers.IO) {
        try {
            // 添加mealTime字段，格式化为ISO格式
            val requestData = mapOf(
                "userId" to dietRecord.userId,
                "foodId" to dietRecord.foodId,
                "amount" to dietRecord.amount,
                "mealTime" to dietRecord.mealTime,
                "mealType" to dietRecord.mealType
            )
            val requestBody = gson.toJson(requestData).toRequestBody("application/json".toMediaType())
            
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/diet-records")
                .post(requestBody)
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    // 后端返回的data直接包含DietRecord对象，需要转换为FoodRecordItem
                    val record = FoodRecordItem(
                        id = (data?.get("id") as? Number)?.toLong() ?: 0L,
                        userId = (data?.get("userId") as? Number)?.toLong() ?: 0L,
                        foodId = (data?.get("foodId") as? Number)?.toLong() ?: 0L,
                        foodName = data?.get("foodName") as? String ?: "",
                        amount = (data?.get("amount") as? Number)?.toDouble() ?: 0.0,
                        totalCalories = (data?.get("totalCalories") as? Number)?.toDouble() ?: 0.0,
                        totalCarbohydrates = (data?.get("totalCarbohydrates") as? Number)?.toDouble() ?: 0.0,
                        totalProtein = (data?.get("totalProtein") as? Number)?.toDouble() ?: 0.0,
                        totalFat = (data?.get("totalFat") as? Number)?.toDouble() ?: 0.0,
                        mealTime = data?.get("mealTime") as? String ?: "",
                        mealType = data?.get("mealType") as? String ?: "",
                        createdAt = data?.get("createdAt") as? String ?: ""
                    )
                    Result.success(record)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "创建饮食记录失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 删除饮食记录
     */
    suspend fun deleteDietRecord(recordId: Long): Result<Boolean> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/diet-records/$recordId")
                .delete()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                Result.success(apiResponse.success)
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 获取用户指定日期的营养汇总
     */
    suspend fun getNutritionSummary(userId: Long, date: String): Result<NutritionSummary> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/diet-records/user/$userId/summary/$date")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            android.util.Log.d("DietApiService", "获取营养汇总请求: userId=$userId, date=$date")
            android.util.Log.d("DietApiService", "获取营养汇总响应: code=${response.code}, body=$responseBody")
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "营养汇总API返回的data: $data")
                    
                    val summary = NutritionSummary(
                        totalCalories = (data?.get("totalCalories") as? Number)?.toDouble() ?: 0.0,
                        totalCarbohydrates = (data?.get("totalCarbohydrates") as? Number)?.toDouble() ?: 0.0,
                        totalProtein = (data?.get("totalProtein") as? Number)?.toDouble() ?: 0.0,
                        totalFat = (data?.get("totalFat") as? Number)?.toDouble() ?: 0.0,
                        recordCount = (data?.get("recordCount") as? Number)?.toInt() ?: 0,
                        date = data?.get("date") as? String ?: date
                    )
                    android.util.Log.d("DietApiService", "解析出的营养汇总: $summary")
                    Result.success(summary)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取营养汇总失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            android.util.Log.e("DietApiService", "获取营养汇总异常", e)
            Result.failure(e)
        }
    }
    
    /**
     * 根据用户ID和日期获取饮食记录
     */
    suspend fun getDietRecordsByDate(userId: Long, date: String): Result<List<DietRecord>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/diet-records/user/$userId/date/$date")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            android.util.Log.d("DietApiService", "获取饮食记录请求: userId=$userId, date=$date")
            android.util.Log.d("DietApiService", "获取饮食记录响应: code=${response.code}, body=$responseBody")
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("DietApiService", "饮食记录API返回的data: $data")
                    // 根据后端逻辑，records在data.records中
                    val records = data?.get("records") as? List<*>
                    val recordList = records?.map { recordData ->
                        val recordMap = recordData as Map<*, *>
                        DietRecord(
                            id = (recordMap["id"] as? Number)?.toLong() ?: 0L,
                            userId = (recordMap["userId"] as? Number)?.toLong() ?: 0L,
                            foodId = (recordMap["foodId"] as? Number)?.toLong() ?: 0L,
                            foodName = recordMap["foodName"] as? String ?: "",
                            amount = (recordMap["amount"] as? Number)?.toDouble() ?: 0.0,
                            mealTime = recordMap["mealTime"] as? String ?: "",
                            mealType = recordMap["mealType"] as? String ?: "",
                            totalCalories = (recordMap["totalCalories"] as? Number)?.toDouble() ?: 0.0,
                            totalCarbohydrates = (recordMap["totalCarbohydrates"] as? Number)?.toDouble() ?: 0.0,
                            totalProtein = (recordMap["totalProtein"] as? Number)?.toDouble() ?: 0.0,
                            totalFat = (recordMap["totalFat"] as? Number)?.toDouble() ?: 0.0,
                            createdAt = recordMap["createdAt"] as? String ?: "",
                            updatedAt = recordMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("DietApiService", "解析出的饮食记录列表大小: ${recordList.size}")
                    Result.success(recordList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取饮食记录失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            android.util.Log.e("DietApiService", "获取饮食记录异常", e)
            Result.failure(e)
        }
    }
}
